/**
 * sql命令的规范
 */
// update已经呗废弃了
// 需要在连接数据库的options配置{useFindAndModify： false}，使用才不会包警告
// DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated.



/**
 * 封装数据库的增删改查的SQL方法
 * NOTE: 错误优先回调
 */
module.exports = {
    insert(CollName, insertData) {
      return new Promise((resolve, reject) => {
        CollName.insertMany(insertData, (err, data) => {
          err ? reject(err) : resolve(data)
        })
      })
    },
    find(CollName, whereObj, showObj, sortObj = {}, num = "") {
      /**
       * whereObj: {
       *  $or: [
       *    {name: 'xxx'},
       *    {password: 'xxx'},
       *    {username: /^xxx$/'}
       *    //正则模糊查找: /^xxx/ /^xxx$/ /xxx$/ new RegExp('/^xxx/')
       *  ]
       * }
       * 
       * sortObj: {
       *  year: -1// -1是降序
       * }
       * */
      return new Promise((resolve, reject) => {
        CollName.find(whereObj, showObj).sort(sortObj).limit(num).exec((err, data) => {
          err ? reject(err) : resolve(data)
        })
      })
    },
    delete(CollName, deleteObj) {
      return new Promise((resolve, reject) => {
        CollName.deleteMany(deleteObj).exec((err, data) => {
          err ? reject(err) : resolve(data)
        })
      })
    },
    /**
     * 
     * @param {Schema} CollName 
     * @param {String} field 
     * @param {Array} aDelete 例如: [ 'id1', 'id2', ... ]
     * 根据id获取删除所有在这个数组中的文档
     */
    delSelected(CollName, field, aDelete) {
      return new Promise((resolve, reject) => {
        CollName.deleteMany({ [field]: { $in: aDelete } }).exec((err, data) => {
          err ? reject(err) : resolve(data)
        })
      })
    },
    modify(CollName, query, update) {
      /*
      update: {
        $set: {tel: 000, ...},
        $inc: { age: 16 } 减则加上复数
      }
      */
      return new Promise((resolve, reject) => {
        CollName.updateMany(query, update).exec((err, data) => {
          err ? reject(err) : resolve(data)
        })
      })
    },
    /**
     * 
     * @param {Schema} CollName 
     * @param {String} field 
     * @param {Array} aFind
     * 根据id获取它们的详细信息 例如: [ 'id1', 'id2', ... ]
     */
    findSelected(CollName, field, aFind) {
      return new Promise((resolve, reject) => {
        CollName.find({
          // 加中括号表示key值也是变量
          [field]: { $in: aFind }
        }, function (err, docs) {
          err ? reject(err) : resolve(docs)
        });
      })
    },
    /**
     * 未测试: 可能$in和.in的作用相同
     */
    findSelected2(CollName, field, aFind) {
      return new Promise((resolve, reject) => {
        CollName.find({ vendorId: mongoose.Types.ObjectId(_vendorId), status: 'Active' })
          .where('category')
          .in(arr)
          .exec((err, data) => {
            err ? reject(err) : resolve(data)
          });
      })
    },
    /**
     * 改了之后返回更新前或后的数据
     */
    updateReturn(CollName, query, update, options = {
      // 默认值配置 options控制选项
      new: true,// - 默认为false。返回修改后的数据。
      upsert: true,// - 默认为false。如果不存在则创建记录。
      setDefaultsOnInsert: {},// 如果upsert选项为true，在新建时插入文档定义的默认值。
      runValidators: false,// 如果值为true，执行Validation(权限)验证。
      sort: true,// 如果有多个查询条件，按顺序进行查询更新。
      select: { _id: 0 } // 设置数据的返回(下划线id不用返回)
    }) {
      return new Promise((resolve, reject) => {
        CollName.findByIdAndUpdate(query, update, options).exec((err, docs) => {
          err ? reject(err) : resolve(docs)
        })
      })
    },
  }